package com.github.wxpay.plus;

import com.github.wxpay.sdk.WXPayRequest;
import com.github.wxpay.sdk.WXPayUtil;
import com.github.wxpay.sdk.WxPaySdkConfig;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.net.InetAddress;
import java.util.Map;

/**
 * 微信支付工具
 */
@Component
@Slf4j
public class WxPayTemplate {

    public static final String SUCCESS_FLAG = "SUCCESS";

    @Autowired
    private WXConfig wxConfig;

    @Autowired
    private WxPaySdkConfig wxPaySdkConfig;

    @Autowired
    private WxPayTemplate wxPayTemplate;


    /**
     * 下单
     * @param wxPayParam 微信支付参数
     * @return
     */
    public Map<String,String> requestPay(WxPayParam wxPayParam) {
        try{
            String nonce_str = WXPayUtil.generateNonceStr();
            //1.封装请求参数
            Map<String,String> map= Maps.newHashMap();
            map.put("appid",wxPaySdkConfig.getAppID());//公众账号ID
            map.put("mch_id",wxPaySdkConfig.getMchID());//商户号
            map.put("nonce_str", nonce_str);//随机字符串
            map.put("body",wxPayParam.getBody());//商品描述
            map.put("out_trade_no",wxPayParam.getOutTradeNo());//订单号
            map.put("total_fee",wxPayParam.getTotalFee()+"");//金额
            map.put("spbill_create_ip", InetAddress.getLocalHost().getHostAddress());//终端IP
            map.put("notify_url",wxConfig.getNotifyUrl());//回调地址
            if(wxPayParam.getOpenid().equals("")){
                map.put("trade_type","NATIVE");//交易类型  : 本地
            }else{
                map.put("trade_type","JSAPI");//交易类型:  小程序
                map.put("openid",wxPayParam.getOpenid());//openId
            }
            String xmlParam  = WXPayUtil.generateSignedXml(map, wxPaySdkConfig.getKey());
            log.info("封装参数:{}",xmlParam);
            //2.发送请求
            WXPayRequest wxPayRequest=new WXPayRequest(wxPaySdkConfig);
            String xmlResult = wxPayRequest.requestWithCert("/pay/unifiedorder", null, xmlParam, false);
            //3.解析返回结果
            Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
            log.info("返回结果:{}",mapResult);
            //返回给移动端需要的参数
            Map<String, String>  result = Maps.newHashMap();
            if("SUCCESS".equals(mapResult.get("return_code"))){   //返回状态码成功
                //如果result-code为失败
                if("SUCCESS".equals(mapResult.get("result_code"))){ //如果成功
                    if(wxPayParam.getOpenid().equals("")) {  //本地支付
                        result.put("codeUrl", mapResult.get("code_url"));  //如果本地支付，会显示二维码
                    }else{  //小程序支付
                        result.put("appId",wxPaySdkConfig.getAppID());
                        result.put("package", "prepay_id=" + mapResult.get("prepay_id"));  //预付单信息
                        result.put("signType","MD5");
                        result.put("nonceStr", WXPayUtil.generateNonceStr());
                        Long timeStamp = System.currentTimeMillis() / 1000;
                        result.put("timeStamp", timeStamp + "");//要将返回的时间戳转化成字符串，不然小程序端调用wx.requestPayment方法会报签名错误
                        //再次签名，这个签名用于小程序端调用wx.requesetPayment方法
                        String sign = WXPayUtil.generateSignature(result,wxConfig.getPartnerKey());
                        result.put("paySign", sign);
                        result.put("appId","");
                    }
                    result.put("orderNo",wxPayParam.getOutTradeNo());
                    result.put("code","SUCCESS");  //成功
                    return result;
                }else {
                    result.put("msg",  mapResult.get("err_code_des" ));  //错误描述
                    result.put("code","RESULT_FAIL");//失败
                    return result;
                }
            }else {
                log.info("调用微信统一下单接口失败",mapResult.get("return_msg"));
                result.put("msg",  mapResult.get("return_msg" ));  //错误描述
                result.put("code","RETURN_FAIL");//返回失败
                return result;
            }
        }catch (Exception ex){
            log.info("调用微信统一下单接口失败",ex);
            return null;
        }
    }


    /**
     * 验证支付结果
     * @param inputStream
     * @return 订单号
     * @throws Exception
     */
    public Map<String,String> validPay(InputStream inputStream) throws Exception {
        String notifyResult = ConvertUtils.convertToString( inputStream);
        Map<String,String> result=Maps.newHashMap();
        //解析
        Map<String, String> map = WXPayUtil.xmlToMap( notifyResult );        //验签
        boolean signatureValid = WXPayUtil.isSignatureValid(map, wxConfig.getPartnerKey());

        if(signatureValid){
            if("SUCCESS".equals(map.get("result_code"))){
                result.put("code","SUCCESS");//成功
                result.put("order_sn", map.get("out_trade_no") );//订单号
                result.put("price", map.get("total_fee") );//订单金额
                //返回订单号
               return result;
            }else {
                log.info("支付回调出错:"+notifyResult);
                result.put("code","FAIL");//失败
                return null;
            }
        }else {
            log.info("支付回调验签失败:"+notifyResult);
            result.put("code","FAIL");//失败
            return result;
        }
    }





}
